<template>
  <el-card>
    <el-row :gutter="6">
      <el-col :span="10">
        <el-card class="box-card">
          <template #header>
            <div class="card-header justify-between">
              <div class="text">用户列表</div>
              <div>
                <el-input
                  v-model="userQuery.userName"
                  placeholder="请输入用户名称"
                  clearable
                  size="small"
                  @keyup.enter="getUserList"
                  width="100"
                />
                <el-button
                  type="primary"
                  size="small"
                  icon="Search"
                  @click="getUserList"
                >
                  筛选
                </el-button>
              </div>
            </div>
          </template>
          <el-table
            row-class-name="table-row-selectable"
            v-loading="userLoading"
            highlight-current-row
            :data="userList"
            style="height: 59vh; width: 50vw"
            @row-click="handleUserListClick"
          >
            <el-table-column prop="userName" label="用户名" />
            <el-table-column prop="phoneNumber" label="手机号" />
            <el-table-column prop="organizationName" label="部门" />
          </el-table>
          <!-- 分页组件 -->
          <pagination
            small
            v-show="userTotal > 0"
            :total="userTotal"
            v-model:page="userQuery.pageNum"
            v-model:limit="userQuery.pageSize"
            :layout="'prev, pager, next'"
            @pagination="getUserList"
          />
        </el-card>
      </el-col>

      <el-col :span="12">
        <el-card class="box-card">
          <template #header>
            <div class="card-header justify-between">
              <div class="text">管理区域</div>
              <div v-if="regionOrganizationTree.length > 0">
                <el-button
                  type="info"
                  plain
                  icon="Sort"
                  size="small"
                  @click="handleToggleExpandAll"
                >
                  展开/折叠
                </el-button>
                <el-button
                  type="primary"
                  @click="saveRegionOrganization"
                  size="small"
                >
                  保存
                </el-button>
                <el-button @click="handleReset" size="small">重置</el-button>
              </div>
            </div>
          </template>
          <el-scrollbar style="height: 70vh">
            <el-tree
              ref="treeTableRef"
              v-loading="loading"
              :data="regionOrganizationTree"
              node-key="id"
              :default-expand-all="isExpandAll"
              show-checkbox
              :expand-on-click-node="false"
              :default-checked-keys="childRegionIds"
              @check="nodeClick"
            >
            </el-tree>
          </el-scrollbar>
        </el-card>
      </el-col>
    </el-row>
  </el-card>
</template>

<script setup lang="ts">
import {
  getUserList as getUserListApi,
  getRegionOrganizationTree as getRegionOrganizationTreeApi,
  saveRegionOrganization as saveRegionOrganizationApi,
  getUserDetail as getUserDetailApi,
} from "@/service/api/system/userDataScope";
import to from "await-to-js";
import Pagination from "@/components/Pagination/index.vue";
import { ElTable } from "element-plus";
import {
  RegionOrganizationMixedNode,
  RegionOrganizationMixedVo,
  SysUserInfoVo,
  SysUserVo,
} from "@/service/api/system/userDataScope/types.ts";
import { BasePageResponse, BaseResponse } from "@/service/api/type.ts";
import {removeButtonFocus} from "@/utils/focus.tsx";

declare type SysUserVoWithExtra = SysUserVo & {
  organizationSelection?: string;
};

// 初始数据
const initUserBO: SysUserVoWithExtra = {
  userName: "",
  email: "",
  nickName: "",
  status: "0",
  phoneNumber: "",
  password: "",
  organizationId: "",
  sex: "",
  id: "",
  identityList: [],
  job: "",
  examine: false,
  superAdmin: false,
  loginDate: undefined,
  loginIp: "",
  regionDataScope: {
    allow: [],
    deny: [],
  },
  organizationDataScope: {
    allow: [],
    deny: [],
  },
  organizationSelection: "",
};
const data = reactive({
  userList: <SysUserVo[]>[],
  userBO: { ...initUserBO },
  // 获取用户BO
  userQuery: {
    userName: "",
    superAdmin: false,
    pageSize: 10,
    pageNum: 1,
    orderByColumn: "createTime",
    orderType: "desc",
  },
});
const { userList, userQuery, userBO } = toRefs(data);

const userTotal = ref(0);
const regionOrganizationTree = ref<RegionOrganizationMixedNode[]>([]);
const childRegionIds = ref<string[]>([]);
const allRegionIds = ref<string[]>([]);
const checkedNodes: any = ref([]);
const loading = ref(false);
const isExpandAll = ref(false);
const treeTableRef = ref(ElTable);
const userLoading = ref(false);
const currentUserId = ref("");
/**
 * 获取用户列表
 */
const getUserList = async (): Promise<boolean> => {
  const [err, res] = await to<BasePageResponse<SysUserVo>, any>(
    getUserListApi(userQuery.value),
  );
  console.log(res);

  if (!err) {
    userList.value = res?.rows ?? [];
    userTotal.value = Number(res?.total ?? 0);

    return true;
  }
  return false;
};

/**
 * 处理用户列表被点击
 * 用户可以直接点击
 * 刷新完之后，也会人为触发点击
 * @param row
 */
const handleUserListClick = async (row?: any) => {
  console.log(row);
  // 先清空默认勾选列表
  childRegionIds.value = []
  allRegionIds.value = []
  // 获取树结构数据
  if (typeof row === "string") {
    currentUserId.value = row;
  } else {
    currentUserId.value = row.id;
  }
  const [err, res] = await to<BaseResponse<RegionOrganizationMixedVo>, any>(
    getRegionOrganizationTreeApi(currentUserId.value),
  );
  if (!err) {
    console.log(res);
    regionOrganizationTree.value = res?.data?.tree ?? [];
    childRegionIds.value = res?.data?.checkedSonIds ?? [];
    allRegionIds.value = res?.data?.checkedIds ?? [];
    console.log(allRegionIds.value, childRegionIds.value,regionOrganizationTree.value);
    setDefaultChecked(regionOrganizationTree.value);

    const [err2, res2] = await to<BaseResponse<SysUserInfoVo>, any>(
      getUserDetailApi(currentUserId.value),
    );
    if (!err2) {
      userBO.value = res2?.data?.user ?? initUserBO;
      // 清空当前勾选，保存时再勾选
      // if (!userBO.value.regionDataScope) {
        userBO.value.regionDataScope = {
          allow: [],
          deny: [],
        };
      // }
      // if (!userBO.value.organizationDataScope) {
        userBO.value.organizationDataScope = {
          allow: [],
          deny: [],
        };
      // }
      console.log(userBO.value);
    }
  }
};

// 初次渲染设置选中状态
const setDefaultChecked = (treeArr: any) => {
  for (let i = 0; i < treeArr.length; i++) {
    let node = treeArr[i];
    // 遍历每个节点并且设置为已勾选
    node.isChecked = allRegionIds.value.some((item) => item === node.id);
    if (node.children && node.children.length > 0) {
      setDefaultChecked(node.children);
    }
  }
};

// 树节点被点击
const nodeClick = (node: any, status: any) => {
  checkedNodes.value = [...JSON.parse(JSON.stringify(status.checkedNodes))];
  console.log(checkedNodes.value, node);
  // 设置勾选状态
  setDynamicChecked(regionOrganizationTree.value);
  console.log(regionOrganizationTree.value);

};

// 遍历permissionTree,设置已勾选的为true
const setDynamicChecked = (treeArr: any) => {
  for (let i = 0; i < treeArr.length; i++) {
    const node = treeArr[i];
    // 找到已勾选列表是否有
    // 有就勾上 没有就不勾
    node.isChecked = checkedNodes.value.some((item: any) => {
      return item.id === node.id;
    });
    if (node.children && node.children.length > 0) {
      setDynamicChecked(node.children); // 递归调用，处理每个子节点
    }
  }
};

// 遍历拿到树形节点中所有选中的节点
const getCheckedNodes = (treeArr: any) => {
  for (let i = 0; i < treeArr.length; i++) {
    let node = treeArr[i];
    if (node.isChecked) {
      if (node.itemType === 0) {
        // 区域节点
        (userBO as any).value.regionDataScope.allow.push(node.id);
      } else {
        // 机构节点
        (userBO as any).value.organizationDataScope.allow.push(node.id);
      }
    }
    if (node.children && node.children.length > 0) {
      getCheckedNodes(node.children); // 递归调用，处理每个子节点
    }
  }
};

/**
 * 处理保存按钮
 */
const saveRegionOrganization = async () => {
  loading.value = true;
  const [err, confirm] = await to<string, string>(
    ElMessageBox.confirm("是否保存当前勾选区域与机构?", "提示", {
      confirmButtonText: "是",
      cancelButtonText: "否",
      type: "warning",
    }),
  );
  if (err === "cancel") {
    ElMessage({ type: "info", message: "已取消保存，恢复到上次加载状态。" });
  } else if (confirm === "confirm") {
    console.log(regionOrganizationTree.value);

    getCheckedNodes(regionOrganizationTree.value);
    console.log(userBO.value);
    userBO.value.loginDate = undefined;
    userBO.value.loginIp = undefined;
    // 若脱敏则删除电话字段
    console.log(userBO.value.phoneNumber);

    if (userBO.value?.phoneNumber?.includes("****")) {
      delete userBO.value.phoneNumber;
    }
    if (userBO.value.nickName) {
      delete userBO.value.nickName;
    }
    const [err2, res2] = await to<BaseResponse<any>, any>(
      saveRegionOrganizationApi(userBO.value),
    );
    if (!err2) {
      ElMessage({
        type: "success",
        message: "保存成功",
      });
      console.log(currentUserId.value);
      childRegionIds.value = []
      allRegionIds.value = []
      await handleUserListClick(currentUserId.value);
    }
  }
  loading.value = false;
};

/**
 * 处理展开折叠
 */
const handleToggleExpandAll = (event: MouseEvent) => {
  isExpandAll.value = !isExpandAll.value;
  let nodes = treeTableRef.value.store.nodesMap;
  for (const node in nodes) {
    nodes[node].expanded = isExpandAll.value;
  }
  removeButtonFocus(event);
};

// 取消保存
const handleReset = async () => {
  const [err] = await to(
    ElMessageBox.confirm("是否重置回到初始勾选状态?", "提示", {
      confirmButtonText: "是",
      cancelButtonText: "否",
      type: "warning",
    }),
  );
  if (!err) {
    await handleUserListClick(currentUserId.value);
    ElMessage({
      type: "success",
      message: "重置成功",
    });
  } else {
    ElMessage({
      type: "info",
      message: "取消成功",
    });
  }
};

onMounted(() => {
  getUserList();
});
</script>

<style scoped lang="scss">
.card-header {
  display: flex;

  .text {
    width: 150px;
    /* background-color: aqua; */
  }

  .el-input {
    margin: 0 5px 0 0;
    width: 200px;
  }
}
</style>
